﻿
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using Nextensions.Net.Protocols.Http;

namespace Nextensions.Net
{
    public class Browser
    {
        private List<string> _cookies = new List<string>();
        private bool _keepState = false;
        private string _currentUrl = "";
        private readonly Regex _reAbsolute = new Regex(@"^https?://", RegexOptions.IgnoreCase | RegexOptions.Compiled);
        private List<KeyValuePair<string, string>> _headers = new List<KeyValuePair<string,string>>();
        private string _serverUrl;

        public HttpResponse Post(string URL, Dictionary<string, string> PostData)
        {
            return Post(URL, PostData, null, null, null, null);
        }

        public HttpResponse Post(string URL, Dictionary<string, string> PostData, Encoding Enc)
        {
            return Post(URL, PostData, Enc, null, null, null);
        }

        public HttpResponse Post(string URL, Dictionary<string, string> PostData, string UserName, string Password)
        {
            return Post(URL, PostData, UserName, Password, null);
        }

        public HttpResponse Post(string URL, Dictionary<string, string> PostData, string UserName, string Password, string Domain)
        {
            return Post(URL, PostData, null, UserName, Password, Domain);
        }

        public HttpResponse Post(string URL, Dictionary<string, string> PostData, Encoding Enc, string UserName, string Password)
        {
            return Post(URL, PostData, Enc, UserName, Password);
        }

        public HttpResponse Post(string URL, Dictionary<string, string> PostData, Encoding Enc, string UserName, string Password, string Domain)
        {
            StringBuilder post = new StringBuilder();

            foreach(KeyValuePair<string, string> pair in PostData)
            {
                string val = pair.Value == null ? "" : pair.Value;

                //if (pair.Key != "__VIEWSTATE") //TODO: Fix, check +... %20 ... space...
                //    val = val.Replace("+", " ");

                post.AppendFormat("{0}={1}&", pair.Key, System.Uri.EscapeDataString(val));
            }

            post.Remove(post.Length - 1, 1);

            return Post(URL, post.ToString(), null, Enc, UserName, Password, Domain);
        }

        public HttpResponse Post(string URL, string PostData)
        {
            return Post(URL, PostData, null, null, null, null, null);
        }

        public HttpResponse Post(string URL, string PostData, string ContentType)
        {
            return Post(URL, PostData, ContentType, null, null, null, null);
        }

        public HttpResponse Post(string URL, string PostData, Encoding Encoding)
        {
            return Post(URL, PostData, null, Encoding, null, null, null);
        }

        public HttpResponse Post(string URL, string PostData, Encoding Enc, string UserName, string Password, string Domain)
        {
            return Post(URL, PostData, null, Enc, UserName, Password, Domain);
        }

        public HttpResponse Post(string URL, string PostData, string ContentType, Encoding Enc, string UserName, string Password, string Domain)
        {
            HttpResponse res = HttpDoRequest(RequestMethods.POST, URL, PostData, ContentType, Enc, UserName, Password, Domain);

            return res;
        }

        public HttpResponse Get(string URL)
        {
            HttpResponse res = HttpDoRequest(RequestMethods.GET, URL, null, null, null, null, null);

            return res;
        }

        private HttpResponse HttpDoRequest(RequestMethods Method, string Url, string PostData, Encoding Encoding, string UserName, string Password, string Domain)
        {
            return HttpDoRequest(Method, Url, PostData, null, Encoding, UserName, Password, Domain);
        }

        private HttpResponse HttpDoRequest(RequestMethods method, string url, string postData, string contentType, Encoding encoding, string userName, string password, string domain)
        {
            if (!URL.IsAbsolute(url))
            {
                url =  URL.Combine(_serverUrl, url);
            }

            _currentUrl = url;
            _serverUrl = Regex.Match(url, @"^[\w]+://[^/]+").Value;

            HttpResponse res = null;

            if (method == RequestMethods.POST)
            {
                res = HTTP.Post(url, postData, contentType, _cookies, _headers, encoding, userName, password, domain);
            }
            else if (method == RequestMethods.GET)
            {
                res = HTTP.Get(url, _cookies, _headers);
            }

            SaveCookies(res.Cookies);

            return res;
        }

        public void AddHeader(string Name, string Value)
        {
            _headers.Add(new KeyValuePair<string,string>(Name, Value));
        }

        private void SaveCookies(List<string> Cookies)
        {
            foreach (string cookie in Cookies)
                _cookies.Add(cookie);
        }
    }
}
